package com.dareway.juc.lock;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantReadWriteLock;

public class readWriteLock {
    //    读锁：在没有任何线程占用写锁的情况下，同一时间可以有多个线程加读锁。
    //    写锁：在没有任何线程占用读锁的情况下，同一时间只能有一个线程加写锁。
    public static void main(String[] args) throws InterruptedException {
        ReentrantReadWriteLock lock = new ReentrantReadWriteLock(true);
//        多个线程同时对读锁加锁。
        //        读锁状态下无法加写锁，反之亦然：


        lock.readLock().lock();
        lock.readLock().lock();
//        lock.writeLock().lock();
        new Thread(() -> {
            lock.writeLock().lock();
            System.out.println("成功获取到写锁！");
            lock.writeLock().unlock();
        }).start();
        System.out.println("释放第一层锁！");
        lock.readLock().unlock();
        TimeUnit.SECONDS.sleep(1);
        System.out.println("释放第二层锁！");
        lock.readLock().unlock();

        //        当一个线程持有写锁的情况下，虽然其他线程不能加读锁，但是线程自己是可以加读锁的
//        "锁降级" 线程添加了读锁和写锁，释放写锁，其他线程也可添加读锁了
//        仅持有读锁的情况下去申请写锁，属于"锁升级"，ReentrantReadWriteLock是不支持的：
        lock.writeLock().lock();
        System.out.println("添加写锁");
        lock.readLock().lock();
        System.out.println("添加读锁");

//        System.out.println(">>>>>>>>>>>>>>>>公平锁测试>>>>>>>>>>>>");
//        Runnable action = () -> {
//            System.out.println("线程 "+Thread.currentThread().getName()+" 将在1秒后开始获取锁...");
//            lock.writeLock().lock();
//            System.out.println("线程 "+Thread.currentThread().getName()+" 成功获取锁！");
//            lock.writeLock().unlock();
//        };
//        for (int i = 0; i < 100; i++) {   //建立10个线程
//            new Thread(action, "T"+i).start();
//        }
    }
}
